<template>
  <div class="article-container">
    <!-- 导航栏 -->
    <NavBar title="文章详情"></NavBar>
    <!-- /导航栏 -->

    <!-- !Object.keys(article).length 判断对象的长度是否为空-->
    <van-loading color="#1989fa" size="24" v-if="!Object.keys(article).length"
      >加载中...</van-loading
    >

    <!-- 文章内容 -->
    <div class="content" v-else>
      <!-- 标题 -->
      <h1 class="title">{{ article.title }}</h1>
      <!-- /标题 -->

      <!-- 关注 -->
      <van-cell center class="user-info" :border="false">
        <!-- 头像 -->
        <van-image
          slot="icon"
          :src="article.aut_photo"
          round
          fit="cover"
          class="avatar"
        />
        <div slot="title" class="name">{{ article.aut_name }}</div>
        <div slot="label" class="pubdate">
          {{ article.pubdate | relativeTime }}
        </div>
        <van-button
          :type="article.is_followed ? 'default' : 'info'"
          round
          size="mini"
          :icon="article.is_followed ? '' : 'plus'"
          class="follow-btn"
          :loading="isLoading"
          @click="onFollow"
          >{{ article.is_followed ? "已关注" : "关注" }}</van-button
        >
      </van-cell>
      <!-- /关注 -->

      <!-- 文章正文 -->
      <div
        class="markdown-body"
        v-html="article.content"
        v-highlight
        ref="article-content"
      ></div>
      <!-- /文章正文 -->

      <!-- 评论列表 -->
      <CommentList
        :source="articleId"
        :list="commentList"
        class="article-list"
        @update-total-count="totalCommentCount = $event"
        @reply-click="onReplyClick"
      ></CommentList>
      <!-- /评论列表 -->
    </div>
    <!-- /文章内容 -->

    <!-- 底部区域 -->
    <div class="article-bottom">
      <van-button
        class="comment-btn"
        type="default"
        round
        size="small"
        @click="isPostShow = true"
        >写评论</van-button
      >
      <van-icon
        :color="article.attitude === 1 ? 'red' : '#777'"
        :name="article.attitude === 1 ? 'good-job' : 'good-job-o'"
        @click="onLiking"
      />

      <!-- 评论数量 -->
      <van-icon name="comment-o" :badge="totalCommentCount" @click="topFn" />

      <van-icon
        :color="article.is_collected ? 'orange' : '#777'"
        :name="article.is_collected ? 'star' : 'star-o'"
        @click="onCollection"
      />
      <van-icon name="share-o" />
    </div>
    <!-- /底部区域 -->

    <!-- 发表评论 -->
    <van-popup v-model="isPostShow" position="bottom" round @opened="getFocus">
      <!-- 这里使用 v-if 的目的是让组件伴随着弹出层的显示进行渲染和销毁，防止加载过的组件不重新渲染导致数据不会重新加载的问题 🌟🌟  -->
      <PostComment
        v-if="isPostShow"
        :target="articleId"
        @post-scucces="onPostSuccess"
        ref="myInput"
        @close="isPostShow = false"
      ></PostComment>
    </van-popup>
    <!-- /发表评论 -->

    <!-- 回复评论 -->
    <van-popup v-model="isReplyShow" position="bottom">
      <!-- 这里使用 v-if 的目的是让组件伴随着弹出层的显示进行渲染和销毁，防止加载过的组件不重新渲染导致数据不会重新加载的问题 🌟🌟  -->
      <CommentReply
        v-if="isReplyShow"
        @close="isReplyShow = false"
        :comment="replyComment"
        :art_id="articleId"
      ></CommentReply>
    </van-popup>
    <!-- /回复评论 -->
  </div>
</template>

<script>
// 引入组件
import NavBar from '@/components/navBar'
import CommentList from './components/components-list'
import PostComment from './components/post-components'
import CommentReply from './components/components-reply'

// 加载文章正文样式
import './github-markdown.css'

// 加载封装的axios接口方法
import {
  getArticleAPI,
  addFollowingAPI,
  deleteFollowingAPI,
  addCollectionAPI,
  deleteCollectionAPI,
  likeArticleAPI,
  dislikeArticleAPI
} from '@/api'

// VantUI组件库的图片预览 --- 只能单独加载🌟🌟🌟
import { ImagePreview } from 'vant'

export default {
  // 注册组件
  components: { CommentReply, PostComment, NavBar, CommentList },
  // 组件名
  name: 'Article',
  // 定义props
  props: {
    // 在组件中获取动态路由参数:🌟
    // 1) this.$route.params.articleId
    // 2) props 传参, 推荐🌟
    articleId: {
      type: String,
      required: true
    }
  },
  // 定义变量
  data () {
    return {
      article: {}, // 文章数据对象
      isLoading: false, // 控制关注按钮的loading状态
      isPostShow: false, // 控制发表评论弹出层的状态
      commentList: [], // 对文章评论数据
      totalCommentCount: 0, // 评论数量
      isReplyShow: false, // 控制回复评论弹出层的状态
      replyComment: {} //  当前回复评论对象
    }
  },
  // 生命周期函数
  created () {
    // 获取新闻详情
    this.getArticle()
  },
  // 定义方法函数
  methods: {
    // 新闻详情
    async getArticle () {
      // 在组件中获取动态路由参数:🌟
      // 1. this.$route.params.articleId
      // const { data } = await getArticleAPI(this.$route.params.articleId)
      // this.article = data.data

      // 2. props传参数
      const { data } = await getArticleAPI(this.articleId)
      this.article = data.data

      // 数据改变影响视图更新(DOM 数据) 不是立即的 —— 如果需要自啊修改数据之后马上操作被该数据影响的视图 DOM，需要把这个代码放到 $nextTick 中
      // this.$nextTick() 是 vue 提供的一个方法
      this.$nextTick(() => {
        this.imagePreview() // 预览图片
      })
    },
    // 预览图片
    imagePreview () {
      // 预览图片操作🌟🌟🌟
      // 1. 获取文章内容 DOM 容器
      const articleContent = this.$refs['article-content']

      // 2. 得到所有的 img 标签
      const imgs = articleContent.querySelectorAll('img')
      // console.log(imgs)

      const imgPaths = [] // 收集所有的图片路径

      // 3. 循环 img 列表， 给 img 注册点击事件
      imgs.forEach((img, index) => {
        img.onclick = function () {
          imgPaths.push(img.src) // 图片的地址
          // 调用预览方法 ——— 直接复制 VantUI组件库的图片预览 方法
          ImagePreview({
            images: imgPaths, // 预览图片路径列表
            startPosition: index, // 指定图片的初始位置（索引值）
            showIndicators:true,
            closeable:true
          })
        }
      })
    },
    // 是否关注用户
    async onFollow () {
      // 开启loading
      this.isLoading = true
      // 已关注，取消关注
      if (this.article.is_followed) {
        await deleteFollowingAPI(this.articleId)
        // this.article.is_followed = false
      } else {
        // 没有关注，添加关注
        await addFollowingAPI(this.articleId)
        // this.article.is_followed = true
      }
      this.article.is_followed = !this.article.is_followed
      // 关闭loading
      this.isLoading = false
    },
    // 是否收藏文章
    async onCollection () {
      this.$toast.loading({
        message: '加载中...',
        forbidClick: true // 禁止背景点击
      })
      // 已收藏，取消收藏
      if (this.article.is_collected) {
        await deleteCollectionAPI(this.articleId)
        // this.article.is_collected = false
      } else {
        // 没有收藏，添加收藏
        await addCollectionAPI(this.articleId)
        // this.article.is_collected = true
      }
      // 更新视图
      this.article.is_collected = !this.article.is_collected
      // 用户未登录无法进行收藏文章
      this.article.is_collected
        ? this.$toast.success('收藏成功')
        : this.$toast.fail('取消收藏成功')
    },
    // 是否点赞文章
    async onLiking () {
      this.$toast.loading({
        message: '加载中...',
        forbidClick: true // 禁止背景点击
      })
      // 已点赞，取消点赞
      if (this.article.attitude === 1) {
        await dislikeArticleAPI(this.articleId)
        this.article.attitude = -1
      } else {
        // 没有点击，添加点赞
        await likeArticleAPI(this.articleId)
        this.article.attitude = 1
      }
      this.article.attitude === 1
        ? this.$toast.success('点赞成功')
        : this.$toast.fail('取消点赞成功')
    },
    // 对文章评论
    onPostSuccess (comment) {
      // console.log(components)

      // 把发布成功的评论数据对象放到评论列表顶部
      this.commentList.unshift(comment)

      // 更新评论的数量
      this.totalCommentCount++

      // 关闭发布评论弹出层
      this.isPostShow = false
    },
    // 滚动到第一条评论条
    topFn () {
      // 建议：用原生的js，因为js代码是在html+css运行后，真实的DOM已经在网页上来，从document往下获取标签是ok的
      // 这种方法既可以实现滚动，也有动画效果
      // scrollIntoView(), 让原生的标签滚动到屏幕的最上面
      this.$nextTick(() => {
        document.querySelector('.article-list').scrollIntoView({
          behavior: 'smooth'
        })
      })
    },
    // 打开弹窗 —— 自动获取焦点，立刻滚动到第一条评论
    getFocus () {
      // 获得焦点后，自动滚动到第一条滚动条
      this.topFn()
    },
    // 回复评论
    onReplyClick (comment) {
      // console.log('onReplyClick', components)

      // 获取当前评论
      this.replyComment = comment

      // 打开回复评论弹窗
      this.isReplyShow = true
    }
  }
}
</script>
<style lang='less' scoped>
// 文章详情加载中
/deep/ .van-loading {
  text-align: center;
  z-index: 9999;
}
// 文章内容
.content {
  position: fixed;
  left: 0;
  right: 0;
  top: 46px;
  bottom: 45px;
  overflow-y: auto;
  // 标题
  .title {
    padding: 15px;
    margin: 0;
    font-size: 20px;
    color: #3a3a3a;
    background-color: #fff;
  }

  // 用户信息
  .user-info {
    // 头像
    .avatar {
      width: 35px;
      height: 35px;
      margin-right: 9px;
    }
    // 名称
    .name {
      font-size: 12px;
      color: #363636;
    }
    // 发布日期
    .pubdate {
      font-size: 9px;
      color: #c2c2c2;
    }
    // 关注按钮
    .follow-btn {
      width: 85px;
      height: 29px;
      border-radius: 15px;
      .van-button__text {
        font-size: 14px;
      }
    }
  }

  // 正文
  .markdown-body {
    padding: 15px;
  }
}
// 底部区域
.article-bottom {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: 44px;
  background: #fff;
  border-top: 1px solid #d8d8d8;
  display: flex;
  justify-content: space-around;
  align-items: center;
  // 按钮
  .comment-btn {
    width: 141px;
    height: 23px;
    font-size: 15px;
    color: #a7a7a7;
    border-radius: 11px;
    border: solid 1px #eeeeee;
  }
  // 字体图标
  .van-icon {
    top: 6px;
    width: 21px;
    height: 35px;
    margin: 0 15px;
  }
  .yellow {
    color: rgb(210, 210, 14);
  }
}
</style>
